package com.sensetime.sample.a;

import android.Manifest;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

import com.sensetime.library.finance.common.app.CameraActivity;
import com.sensetime.library.finance.common.type.ResultCode;
import com.sensetime.library.finance.common.type.Size;
import com.sensetime.library.finance.common.util.DeviceUtil;
import com.sensetime.library.finance.common.util.FileUtil;
import com.sensetime.library.finance.ocr.card.IdCardApi;
import com.sensetime.library.finance.ocr.card.IdCardInfo;
import com.sensetime.library.finance.ocr.card.NativeIdCardKey;
import com.sensetime.library.finance.ocr.card.NativeIdCardSide;
import com.sensetime.library.finance.ocr.card.OnIdCardScanListener;


import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created on 2016/11/23 15:55.
 *
 * @author Han Xu
 */
public class IdCardActivity extends CameraActivity {

    public static final String EXTRA_CARD_SIDE = "extra_card_side";
    public static final String EXTRA_ONLY_NAME_NUMBER = "extra_ony_name_number";

    private static final String FILES_PATH = Environment.getExternalStorageDirectory().getPath() + "/sensetime/";
    private static final String MODEL_FILE_NAME = "M_Idcard_Mobile_2.5.3.model";
    private static final String LICENSE_FILE_NAME = "SenseID_OCR.lic";

    //    #Set your API Key & Secret here.
    private static final String API_KEY = "eb9eeb9198674422b19cd4bbeae2faab";
    private static final String API_SECRET = "b34cbc59e1084085a29e652e8ed9f505";

    private static final long SHOW_ONE_SIDE_SUCCESS_DELAY = 1000;

    private boolean mIsNameNumberOnly = false;
    private boolean mIsStopped = true;
    private boolean mIsNewTipSet = false;
    private int mSide = NativeIdCardSide.CV_FINANCE_IDCARD_SIDE_FRONT;
    private int mLastSuccessSide = -1;
    private long mOneSideSuccessTime = -1L;

    private ExecutorService mExecutor = null;

    private View mLoadingView = null;

    private OverlayView mOverlayView = null;

    private OnIdCardScanListener mListener = new OnIdCardScanListener() {
        @Override
        public void onError(ResultCode resultCode) {
            setResult(convertResultCode(resultCode));
            finish();
        }

        @Override
        public void onSuccess(IdCardInfo idCardInfo) {
            CardInfoHolder.setCardInfo(idCardInfo);
            setResult(RESULT_OK);
            finish();
        }

        @Override
        public void onOnlineCheckBegin() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mLoadingView.setVisibility(View.VISIBLE);
                }
            });
        }

        @Override
        public void onOneSideSuccess(IdCardInfo idCardInfo) {
            mLastSuccessSide = idCardInfo.getSide();
            mOneSideSuccessTime = SystemClock.uptimeMillis();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mOverlayView.setText(R.string.scan_success, Color.parseColor("#53EFA0"));
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!checkPermission(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            setResult(RESULT_CODE_NO_PERMISSIONS);
            finish();
            return;
        }

        setContentView(R.layout.activity_idcard);

        findViewById(R.id.img_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

        mSide = getIntent().getIntExtra(EXTRA_CARD_SIDE, NativeIdCardSide.CV_FINANCE_IDCARD_SIDE_FRONT);
        mIsNameNumberOnly = getIntent().getBooleanExtra(EXTRA_ONLY_NAME_NUMBER, false);
        mOverlayView = ((OverlayView) findViewById(R.id.overlay));
        mOverlayView.setText(mSide == NativeIdCardSide.CV_FINANCE_IDCARD_SIDE_UNKNOWN ? R.string.scan_tip_auto : (mSide == NativeIdCardSide.CV_FINANCE_IDCARD_SIDE_FRONT ? R.string.scan_tip_front : R.string.scan_tip_back),
                Color.WHITE);
        mLoadingView = findViewById(R.id.pb_loading);

        initCameraView(R.id.camera_preview, false, null, DeviceUtil.getScreenSize(this));

        File dir = new File(FILES_PATH);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        FileUtil.copyAssetsToFile(getApplicationContext(), MODEL_FILE_NAME, FILES_PATH + MODEL_FILE_NAME);
        FileUtil.copyAssetsToFile(getApplicationContext(), LICENSE_FILE_NAME, FILES_PATH + LICENSE_FILE_NAME);
        ResultCode result = IdCardApi.init(FILES_PATH + LICENSE_FILE_NAME, FILES_PATH + MODEL_FILE_NAME, API_KEY, API_SECRET, mListener);
        if (result != ResultCode.OK) {
            setResult(convertResultCode(result));
            finish();
        }
        startDetectThread();
    }

    @Override
    protected void onPause() {
        mIsStopped = true;
        IdCardApi.cancel();
        destroyExecutor();
        mLoadingView.setVisibility(View.GONE);
        setResult(RESULT_CANCELED);
        finish();
        super.onPause();
    }

    private void startDetectThread() {
        mExecutor = Executors.newSingleThreadExecutor();
        mExecutor.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (mIsStopped) {
                        break;
                    }

                    byte[] imageData = getPreviewData();
                    if (imageData == null) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        continue;
                    }

                    IdCardApi.inputScanImage(imageData,
                            getPreviewSize(),
                            mOverlayView.getCardRect(),
                            mSide,
                            mIsNameNumberOnly ? NativeIdCardKey.KEY_NAME_NUMBER : NativeIdCardKey.KEY_ALL,
                            getCameraOrientation(),
                            getScreenSize());

                    if (mLastSuccessSide > -1 && !mIsNewTipSet) {
                        if (SystemClock.uptimeMillis() - mOneSideSuccessTime > SHOW_ONE_SIDE_SUCCESS_DELAY) {
                            mOneSideSuccessTime = -1L;
                            mIsNewTipSet = true;
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mOverlayView.setText(mLastSuccessSide == NativeIdCardSide.CV_FINANCE_IDCARD_SIDE_FRONT ?
                                            R.string.scan_tip_back :
                                            R.string.scan_tip_front, Color.WHITE);
                                }
                            });
                        }
                    }

                    if (mIsStopped) {
                        break;
                    }
                }
            }
        });
        mIsStopped = false;
    }

    private void destroyExecutor() {
        if (mExecutor == null) {
            return;
        }
        mExecutor.shutdown();
        try {
            mExecutor.awaitTermination(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mExecutor = null;
    }

    private Size getScreenSize() {
        WindowManager manager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        return new Size(display.getWidth(), display.getHeight());
    }
}